<?php

declare(strict_types=1);

namespace App\Common\Middleware;
use App\Common\Constants\ErrorCode;
use Exception;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Context;
use Phper666\JWTAuth\JWT;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class JwtAuthMiddleware implements MiddlewareInterface
{
    /**
     * @var HttpResponse
     */

    protected $response;
    protected $prefix = 'Bearer';
    protected $jwt;

    /**
     * The URIs that should be excluded from JWT verification.
     * 201225 jwt验证排除
     * @var array
     * @author liule
     */
    protected $except = [
        '/v1/api/coupon/pic',
        '/v1/api/getNearShop',
        '/v1/app/order/widget',
        '/v1/api/tomorrow_share',
        '/v1/shop'
    ];


    public function __construct(HttpResponse $response, JWT $jwt)
    {
        $this->response = $response;
        $this->jwt = $jwt;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // jwt验证排除
        $uri = $request->getUri()->getPath();
        if (array_key_exists($uri, array_flip($this->except))) return $handler->handle($request);
        $isValidToken = false;
        try {
            if($this->jwt->checkToken()){
                $isValidToken = true;
            }
        } catch (Exception $e) {
                $data = [
                    'code' =>ErrorCode::AUTH_TOKEN_ERROR,
                    'msg' =>ErrorCode::getMessage(ErrorCode::AUTH_TOKEN_ERROR),
                    'data' => [],
                ];
                return $this->response->json($data);
        }
        if ($isValidToken) {
            $jwtData = $this->jwt->getParserData();
            //更改上下文，写入用户信息
            //User模型自行创建
            $request = Context::get(ServerRequestInterface::class);
            if($jwtData['jwt_scene'] == 'default'){
                //Web后台场景
                $request = $request->withAttribute('uid', $jwtData['uid']);
            } elseif ($jwtData['jwt_scene'] == 'miniProgram'){
                //小程序场景
                $request = $request->withAttribute('mid', $jwtData['mid']);
            } elseif ($jwtData['jwt_scene'] == 'shopApp'){
                // 商家登录场景
                $request = $request->withAttribute('shop_id', $jwtData['shop_id']);
                $request = $request->withAttribute('phone', $jwtData['phone']);
            }
            Context::set(ServerRequestInterface::class, $request);
            return $handler->handle($request);
        }

    }
}
